package com.qyl.framework.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.qyl.framework.base.protocol.RequestProto;
import com.qyl.framework.base.value.BlockingRequestValue;
import com.qyl.framework.client.impl.RPCClient;

/**
 * 
 * @author created by 齐翌来（qiyilai@foxmail.com）
 * 
 * 2019年4月20日
 * 
 * @description 代理模式的实现
 *
 */
public class RpcInvokeProxy<T> implements InvocationHandler {
	
	private RPCClient rpcClient; 
	
	private T targetObject;
	
	private static final Logger logger = LoggerFactory.getLogger(RpcInvokeProxy.class);
	
	@SuppressWarnings("unchecked")
	public T bind(T targetObj) {
		targetObject = targetObj;
		Object object = Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), this);
		return (T)object;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		long requestId = System.currentTimeMillis();
		String className = targetObject.getClass().getName();
		String methodName = method.getName();
		
		Class<?>[] paramClasses = null;
		
		if (args != null && args.length > 0) {
			paramClasses = new Class[args.length];
			for (int i = 0; i < args.length; i++) {
				paramClasses[i] = args[i].getClass();
			}
		}
		
		RequestProto proto = new RequestProto(requestId, className, methodName, paramClasses, args);
		BlockingRequestValue request = rpcClient.send(proto);
		logger.info("RpcInvokeProxy execution requestId={}, {}【{}】", requestId, className, methodName);
		return request.getValue(requestId);
	}

	public RpcInvokeProxy(RPCClient rpcClient) {
		this.rpcClient = rpcClient;
	}
}
